package logica_de_presentacion;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyVetoException;
import java.util.HashSet;

import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.table.AbstractTableModel;

import comun.Capitulo;
import comun.CapituloVistaNoSi;
import comun.Serie;
import comun.Usuario;
import comun.ValoracionCapitulo;
import logica_de_negocio.ExcepDeleteOnCascade;
import logica_de_negocio.FaltanDatosEnLaBaseDeDatos;
import logica_de_negocio.excepAnadirDupli;
import logica_de_negocio.gestorCapitulo;
import logica_de_negocio.gestorCapituloVistaNoSi;
import logica_de_negocio.gestorSerie;
import logica_de_negocio.gestorValoracionCapitulo;
import logica_de_presentacion.FormularioAnadirModificarValoracion;

public class TablaCapitulo extends JInternalFrame implements ActionListener,
		InternalFrameListener {

	private static final long serialVersionUID = 1L;
	private JTable tablaDatos;
	private JButton jbDetalles, jbVerComen, jbEliminarValorar,
			jbModificarMarcarVis, jbSalir;
	private JScrollPane scrollPane;
	private JPanel jpBotones;
	private HashSet<Capitulo> lc;
	private MenuInicial clasePadre;
	private FormularioAnadirModificarCapitulo formularioAnadirModificarCapitulo;
	private Usuario usuActual;
	private ValoracionCapitulo vc;

	private boolean bolFiltit = false;
	private String titulo = null;
	private JButton jbTitulo;

	private boolean bolFilDir = false;
	private String filDir = null;
	private JButton jbFilDir;

	private boolean bolFilPais = false;
	private String filPais = null;
	private JButton jbFilPais;

	private FormularioAnadirModificarValoracion formularioAnadirModificarValoracion;

	public TablaCapitulo(MenuInicial clasePadre, Usuario usuActual) {

		super("Listar capitulo", true, false, false, false);
		this.setVisible(true);
		this.setSize(1000, 500);
		this.usuActual = usuActual;
		this.clasePadre = clasePadre;
		this.subCompo();
	}

	public void subCompo() {

		this.getContentPane().setLayout(new BorderLayout());
		// TABLA
		// CREAMOS UN SCROLLPANE Y LE ANADIMOS LA TABLA
		scrollPane = new JScrollPane(tablaDatos);
		// ANADIMOS EL SCROLLPANE AL PANEL
		this.add(scrollPane, "Center");
		jpBotones = new JPanel(new FlowLayout());
		jbDetalles = new JButton("Ver detalles");
		jbDetalles.addActionListener(this);
		jbDetalles.setMnemonic(KeyEvent.VK_V);
		jbDetalles
				.setToolTipText("Muestra mas detalles del capitulo selecionada");
		jpBotones.add(jbDetalles);

		jbVerComen = new JButton("Comentarios");
		jbVerComen.addActionListener(this);
		jbVerComen.setMnemonic(KeyEvent.VK_C);
		jbVerComen
				.setToolTipText("Mostrar la lista de comenatrios de esa pelicula");
		jpBotones.add(jbVerComen);

		if (usuActual.isEsAdmin()) {
			jbModificarMarcarVis = new JButton("Modificar");
			jbModificarMarcarVis.addActionListener(this);
			jbModificarMarcarVis.setMnemonic(KeyEvent.VK_M);
			jbModificarMarcarVis
					.setToolTipText("Modificar capitulo de la base de datos");
			jpBotones.add(jbModificarMarcarVis);

			jbEliminarValorar = new JButton("Eliminar");
			jbEliminarValorar.addActionListener(this);
			jbEliminarValorar.setMnemonic(KeyEvent.VK_E);
			jbEliminarValorar
					.setToolTipText("Eliminar capitulo de la base de datos");
			jpBotones.add(jbEliminarValorar);

		} else {
			jbModificarMarcarVis = new JButton("Marcar Vista");
			jbModificarMarcarVis.addActionListener(this);
			jbModificarMarcarVis.setMnemonic(KeyEvent.VK_M);
			jbModificarMarcarVis
					.setToolTipText("Marcar como vista el capitulo selecionada");
			jpBotones.add(jbModificarMarcarVis);

			jbEliminarValorar = new JButton("Valorar");
			jbEliminarValorar.addActionListener(this);
			jbEliminarValorar.setMnemonic(KeyEvent.VK_C);
			jbEliminarValorar
					.setToolTipText("Comentar o/y valorar el capitulo de la base de datos");
			jpBotones.add(jbEliminarValorar);
		}

		jbTitulo = new JButton("Filtro Titulo Serie");
		jbTitulo.addActionListener(this);
		jbTitulo.setToolTipText("Anadir filtro por Titulo");
		jpBotones.add(jbTitulo);

		jbFilDir = new JButton("Filtro Director");
		jbFilDir.addActionListener(this);
		jbFilDir.setToolTipText("Anadir filtro por Director");
		jpBotones.add(jbFilDir);

		jbFilPais = new JButton("Filtro Pais");
		jbFilPais.addActionListener(this);
		jbFilPais.setToolTipText("Anadir filtro por Pais");
		jpBotones.add(jbFilPais);

		jbSalir = new JButton("Salir");
		jbSalir.addActionListener(this);
		jbSalir.setMnemonic(KeyEvent.VK_S);
		jbSalir.setToolTipText("Salir  de la tabla");
		jpBotones.add(jbSalir);

		this.getContentPane().add(jpBotones, "South");
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		JButton botonPulsado = (JButton) e.getSource();
		gestorCapitulo gc = new gestorCapitulo();
		if (botonPulsado == jbDetalles) {
			try {
				String titulo = (String) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 0);
				String nombre = (String) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 2);
				int num_cap = (int) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 4);
				gestorSerie gs = new gestorSerie();
				Serie s;
				try {
					s = gs.getSerie(titulo);
					Capitulo cap = gc.getCapitulo(s.getId_s(), nombre, num_cap);
					JOptionPane.showMessageDialog(new Frame(), cap.toString());
				} catch (FaltanDatosEnLaBaseDeDatos e1) {
					JOptionPane.showMessageDialog(new Frame(), e1.getFalta());
				} catch (ClassNotFoundException e1) {
					JOptionPane.showMessageDialog(new Frame(),
							"No hay informacion en la base de datos");
					this.dispose();
				}
			} catch (IndexOutOfBoundsException sinEle) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay niguna fila selecionada");
			}
		}

		if (botonPulsado == jbVerComen) {
			String titulo = (String) tablaDatos.getValueAt(
					tablaDatos.getSelectedRow(), 0);
			String nombre = (String) tablaDatos.getValueAt(
					tablaDatos.getSelectedRow(), 2);
			int num_cap = (int) tablaDatos.getValueAt(
					tablaDatos.getSelectedRow(), 4);
			try {
				gestorSerie gs = new gestorSerie();
				Serie s = gs.getSerie(titulo);
				int id = gc.getCapitulo(s.getId_s(), nombre, num_cap).getId_c();
				TablaValoracion tablaValoracion = new TablaValoracion(false, id);
				tablaValoracion.cargar();
				clasePadre.add(tablaValoracion);
				try {
					tablaValoracion.setSelected(true);
				} catch (PropertyVetoException e1) {
				}
				tablaValoracion.toFront();
				this.refreshTable();
			} catch (IndexOutOfBoundsException sinEle) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay niguna fila selecionada");
			} catch (NullPointerException sinEle2) {
				// CUANDO NO HAY NADA
			} catch (FaltanDatosEnLaBaseDeDatos e1) {
				JOptionPane.showMessageDialog(new Frame(), e1.toString());
			} catch (ClassNotFoundException e2) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay informacion en la base de datos");
				this.dispose();
			}
		}

		if (botonPulsado == jbModificarMarcarVis) {

			try {
				String titulo = (String) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 0);
				String nombre = (String) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 2);
				int num_cap = (int) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 4);
				lc = gc.getCapitulos();
				gestorSerie gs = new gestorSerie();
				Serie s;
				try {
					s = gs.getSerie(titulo);
					Capitulo cap = gc.getCapitulo(s.getId_s(), nombre, num_cap);
					if (usuActual.isEsAdmin()) {
						formularioAnadirModificarCapitulo = new FormularioAnadirModificarCapitulo(
								true, cap.getNum_cap(), cap.getNum_temp(),
								cap.getFecha_emi());
						formularioAnadirModificarCapitulo.cargarMO(cap);
						formularioAnadirModificarCapitulo
								.addInternalFrameListener(this);
						clasePadre.getPanelEscritorio().add(
								formularioAnadirModificarCapitulo);
						formularioAnadirModificarCapitulo.setSelected(true);
						formularioAnadirModificarCapitulo.toFront();
					} else {
						marcarComoVista(cap);
					}
				} catch (FaltanDatosEnLaBaseDeDatos e1) {
					JOptionPane.showMessageDialog(new Frame(), e1.getFalta());
				} catch (PropertyVetoException e1) {

				}
			} catch (IndexOutOfBoundsException sinEle) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay niguna fila selecionada");
			} catch (ClassNotFoundException e2) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay informacion en la base de datos");
				this.dispose();
			}
		}

		if (botonPulsado == jbEliminarValorar) {
			try {
				String titulo = (String) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 0);
				String nombre = (String) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 2);
				int num_cap = (int) tablaDatos.getValueAt(
						tablaDatos.getSelectedRow(), 4);
				gestorSerie gs = new gestorSerie();
				Serie s;
				Capitulo cap = null;
				try {
					s = gs.getSerie(titulo);
					cap = gc.getCapitulo(s.getId_s(), nombre, num_cap);
					if (usuActual.isEsAdmin()) {
						eliminarCapitulo(cap.getId_c());
					} else {
						gestorValoracionCapitulo gvc = new gestorValoracionCapitulo();
						vc = gvc.getValoracionCapitulo(usuActual.getId_u(),
								cap.getId_c());
						comentarValorar();

					}
				} catch (FaltanDatosEnLaBaseDeDatos e1) {
					vc = new ValoracionCapitulo();
					vc.setId_c(cap.getId_c());
					vc.setId_u(usuActual.getId_u());
					comentarValorar();
				} catch (ClassNotFoundException e1) {
					JOptionPane.showMessageDialog(new Frame(),
							"No hay informacion en la base de datos");
					this.dispose();
				}
			} catch (IndexOutOfBoundsException sinEle) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay niguna fila selecionada");
			}
		}

		if (botonPulsado == jbTitulo) {

			if (bolFiltit) {
				int res = JOptionPane.showConfirmDialog(new Frame(),
						"Desea retirar el filtro");
				if (res == 0) {
					bolFiltit = false;
					try {
						this.refreshTable();
					} catch (ClassNotFoundException e1) {
						JOptionPane.showMessageDialog(new Frame(),
								"No hay informacion en la base de datos");
						this.dispose();
					}
				}
			} else {
				String res = JOptionPane.showInputDialog(new Frame(),
						"Indique el titulo de la Serie");
				if (res != null) {
					titulo = res;
					bolFiltit = true;
				}
				try {
					this.refreshTable();
				} catch (ClassNotFoundException e1) {
					JOptionPane.showMessageDialog(new Frame(),
							"No hay informacion en la base de datos");
					this.dispose();
				}
			}
		}

		if (botonPulsado == jbSalir) {
			this.dispose();
		}
	}

	private void comentarValorar() {

		formularioAnadirModificarValoracion = new FormularioAnadirModificarValoracion(
				vc.getPuntuacion(), vc.getComentario());
		formularioAnadirModificarValoracion.addInternalFrameListener(this);
		clasePadre.add(formularioAnadirModificarValoracion);
		try {
			formularioAnadirModificarValoracion.setSelected(true);
		} catch (PropertyVetoException e) {
		}

	}

	private void marcarComoVista(Capitulo cap) throws ClassNotFoundException {

		gestorCapituloVistaNoSi gvns = new gestorCapituloVistaNoSi();
		CapituloVistaNoSi cvns = new CapituloVistaNoSi();
		cvns.setId_u(usuActual.getId_u());
		cvns.setId_c(cap.getId_c());
		cvns.setVista(true);

		try {
			gvns.addCapituloVistaNoSi(cvns);
			if (gvns.anadido(cvns)) {
				JOptionPane.showMessageDialog(new Frame(),
						"Capitulo marcado como visto");
				this.refreshTable();
			}
		} catch (excepAnadirDupli e) {

			cvns = null;
			try {
				cvns = gvns.getCapituloVistaNoSi(cap.getId_c(),
						usuActual.getId_u());
				if (cvns.isVista()) {
					int res = JOptionPane
							.showConfirmDialog(new Frame(),
									"El Capitulo ya esta marcada como vista, Desea desmarcarla?");
					// YES=0, NO=1,Cancel =2
					if (res == 0) {
						cvns.setVista(false);
					}
					if (gvns.modificarCapituloVistaNoSi(cvns)) {
						JOptionPane.showMessageDialog(new Frame(),
								"Capitulo desmarcada");
					}
					this.refreshTable();
				} else {
					cvns.setVista(true);
					if (gvns.modificarCapituloVistaNoSi(cvns)) {
						JOptionPane.showMessageDialog(new Frame(),
								"Capitulo marcado como vista");
						this.refreshTable();
					}
				}
			} catch (FaltanDatosEnLaBaseDeDatos e1) {
				JOptionPane.showMessageDialog(new Frame(), e1.getFalta());
			}
		} catch (FaltanDatosEnLaBaseDeDatos e) {
			JOptionPane.showMessageDialog(new Frame(), e.getFalta());
		}
	}

	public void cargarCapitulo() throws ClassNotFoundException {
		gestorCapitulo gc = new gestorCapitulo();
		lc = gc.getCapitulos();
		crearTabla();
		this.setVisible(true);
		subCompo();
	}

	public void crearTabla() throws ClassNotFoundException {

		tablaDatos = null;// VACIAMOS SI EXISTE ALUGUNA
		myTable tmp = new myTable();
		tablaDatos = new JTable(tmp);

		tablaDatos.setPreferredScrollableViewportSize(new Dimension(200, 200));
		tablaDatos.setEnabled(true);

		// QUE PODAMOS SELECIONAR LAS FILAS
		tablaDatos.setRowSelectionAllowed(true);

		// QUE SE ACTUALICE (La tabla que contiene)
		tmp.fireTableDataChanged();

		// SI QUEREMOS QUE LA TABLA LLENE POR COMPLETO LA VENTANA EN LA ALTURA
		tablaDatos.setFillsViewportHeight(false);

		// CREAR UNA ORDENACION AUTOMATICA
		tablaDatos.setAutoCreateRowSorter(true);

	}

	private void refreshTable() throws ClassNotFoundException {
		gestorCapitulo gc = new gestorCapitulo();
		lc = gc.getCapitulos();
		myTable tpm = (myTable) tablaDatos.getModel();
		tpm.setData();
		tpm.fireTableDataChanged();

	}

	private void eliminarCapitulo(int id_c) throws ClassNotFoundException {

		gestorCapitulo gc = new gestorCapitulo();
		boolean corec = false;
		try {
			corec = gc.borrar(id_c, new ExcepDeleteOnCascade());
		} catch (ExcepDeleteOnCascade e) {
			int res = JOptionPane
					.showConfirmDialog(
							new Frame(),
							"Al eliminar el capitulo tambien se eliminaran los comentarios de los usuarios y estos dejaran de seguir el capitulo");
			// YES=0, NO=1,Cancel =2
			if (res == 0) {
				e.setAceptado(true);
				try {
					corec = gc.borrar(id_c, e);
				} catch (ExcepDeleteOnCascade e1) {
				}
			}
		}
		if (corec == true) {
			JOptionPane.showMessageDialog(new Frame(),
					"Se ha borrado correctamente el capitulo");
			this.refreshTable();
		} else {
			JOptionPane.showMessageDialog(new Frame(),
					"No se ha borrado el capitulo");
		}

	}

	class myTable extends AbstractTableModel {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private String[] columName;
		private Object[][] data;

		public myTable() throws ClassNotFoundException {

			super();

			if (usuActual.isEsAdmin()) {
				String[] col = { "Titulo", "Director", "Nombre", "N_Temp.",
						"N_Capitulo" };
				columName = new String[5];
				columName = col;
			} else {
				String[] col = { "Titulo", "Director", "Nombre", "N_Temp.",
						"N_Capitulo", "Visto" };
				columName = new String[6];
				columName = col;
			}

			setData();
		}

		@Override
		public int getColumnCount() {
			return columName.length;
		}

		@Override
		public int getRowCount() {
			return data.length;
		}

		@Override
		public String getColumnName(int col) {
			return columName[col];
		}

		@Override
		public Object getValueAt(int row, int col) {

			return data[row][col];
		}

		public Serie getSerie(int id_s) throws FaltanDatosEnLaBaseDeDatos,
				ClassNotFoundException {
			gestorSerie gs = new gestorSerie();
			return gs.getSerie(id_s);
		}

		public void setData() throws ClassNotFoundException {

			int filas = lc.size();
			int cont = 0;

			Object[][] data2 = new Object[filas][];

			// RELLENO DATOS
			for (Capitulo c : lc) {
				boolean add = false;
				try {
					Serie s = getSerie(c.getId_s());
					if (bolFiltit) {

						if (s.getTitulo().equals(titulo)) {
							add = true;
						} else {
							add = false;
						}
					} else {
						add = true;
					}

					if (seguir(add)) {
						if (bolFilPais) {
							if (s.getPais().equals(filPais)) {
								add = true;
							} else {
								add = false;
							}
						} else {
							add = true;
						}
					}

					if (seguir(add)) {
						if (bolFilDir) {
							if (s.getDirector().equals(filDir)) {
								add = true;
							} else {
								add = false;
							}
						} else {
							add = true;
						}
					}
					if (seguir(add)) {
						if (usuActual.isEsAdmin()) {
							Object[] a = { s.getTitulo(), s.getDirector(),
									c.getNombre(), c.getNum_temp(),
									c.getNum_cap() };
							data2[cont] = a;
							cont++;
						} else {
							Object[] a = { s.getTitulo(), s.getDirector(),
									c.getNombre(), c.getNum_temp(),
									c.getNum_cap(), capVisto(c) };
							data2[cont] = a;
							cont++;
						}
					}

				} catch (FaltanDatosEnLaBaseDeDatos e) {
					JOptionPane.showMessageDialog(new Frame(), e.getFalta());
				}
			}

			if (cont == 0) {
				JOptionPane
						.showMessageDialog(new Frame(),
								"No hay Capitulos que cumplan las condiciones\nSe retiraran los filtros");
				bolFiltit = false;
				bolFilPais = false;
				bolFilDir = false;

				data = new Object[filas][];
				try {
					data = todas();
				} catch (FaltanDatosEnLaBaseDeDatos e) {
					JOptionPane.showMessageDialog(new Frame(), e.getFalta());
				}

			} else {
				data = new Object[cont][];
				for (int i = 0; i < cont; i++) {// PORQUE data2 mayor que data
					data[i] = data2[i];
				}
			}
		}

		private boolean seguir(boolean add) {

			boolean dev = false;

			if (add == true) {
				dev = true;
			}

			return dev;

		}

		private Object[][] todas() throws FaltanDatosEnLaBaseDeDatos,
				ClassNotFoundException {

			Object[][] data = new Object[lc.size()][];
			int cont = 0;

			for (Capitulo c : lc) {
				Serie s = getSerie(c.getId_s());
				if (usuActual.isEsAdmin()) {
					Object[] a = { s.getTitulo(), s.getDirector(),
							c.getNombre(), c.getNum_temp(), c.getNum_cap() };
					data[cont] = a;
					cont++;
				} else {
					Object[] a = { s.getTitulo(), s.getDirector(),
							c.getNombre(), c.getNum_temp(), c.getNum_cap(),
							capVisto(c) };
					data[cont] = a;
					cont++;
				}
			}

			return data;
		}

		private boolean capVisto(Capitulo c) throws ClassNotFoundException {
			boolean dev = false;
			gestorCapituloVistaNoSi gcvns = new gestorCapituloVistaNoSi();
			try {
				CapituloVistaNoSi capituloVistaNoSi = gcvns
						.getCapituloVistaNoSi(c.getId_c(), usuActual.getId_u());
				dev = capituloVistaNoSi.isVista();
			} catch (FaltanDatosEnLaBaseDeDatos e) {

			}
			return dev;
		}
	}

	@Override
	public void internalFrameOpened(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameClosing(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameClosed(InternalFrameEvent e) {

		if (e.getSource() == formularioAnadirModificarCapitulo) {
			try {
				this.refreshTable();
			} catch (ClassNotFoundException e1) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay informacion en la base de datos");
				this.dispose();
			}
		}

		if (formularioAnadirModificarValoracion == e.getSource()) {
			vc.setComentario(formularioAnadirModificarValoracion.getComen());
			vc.setPuntuacion(formularioAnadirModificarValoracion.getVal());
			gestorValoracionCapitulo gvc = new gestorValoracionCapitulo();
			try {
				gvc.addValoracionCapitulo(vc);
			} catch (excepAnadirDupli e1) {
				boolean core;
				try {
					core = gvc.modificarValoracionCapitulo(vc);
					if (core) {
						JOptionPane.showMessageDialog(new Frame(),
								"El Capitulo se ha revalorado");
					} else {
						JOptionPane.showMessageDialog(new Frame(),
								"_NO_ se ha revalorado el Capitulo");
					}
				} catch (ClassNotFoundException e2) {
					JOptionPane.showMessageDialog(new Frame(),
							"No hay informacion en la base de datos");
					this.dispose();
				}

			} catch (FaltanDatosEnLaBaseDeDatos e1) {
				JOptionPane.showMessageDialog(new Frame(), e1.getFalta());
			} catch (ClassNotFoundException e1) {
				JOptionPane.showMessageDialog(new Frame(),
						"No hay informacion en la base de datos");
				this.dispose();
			}
			if (gvc.isVal(vc)) {
				JOptionPane.showMessageDialog(new Frame(),
						"Se ha valorado la Capitulo ");
			}
		}
	}

	@Override
	public void internalFrameIconified(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameDeiconified(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameActivated(InternalFrameEvent e) {
	}

	@Override
	public void internalFrameDeactivated(InternalFrameEvent e) {
	}
}
